<template>
    <video id="video-background" class="video-js vjs-fill vjs-fluid" muted autoplay loop>
        <source src="../../assets/bg.mp4" type="video/mp4" />
    </video>
    <div class='actionArea'>
        <el-card style="width: 150px;height: 40px;margin-bottom: 10px" shadow="always">分数:<span style='color:red'>{{
            count }}</span></el-card>
        <el-button type="primary" :disabled="begin" @click="BeginGame">开始</el-button>
        <el-button type="primary" :disabled="!begin" @click="ReatartGame">重新开始</el-button>
        <div class="slider-demo-block">
            <span class="demonstration" style="width: 100px;"><el-text class="mx-1" type="danger">速度间隔</el-text></span>
            <el-slider v-model="speed" />
        </div>
    </div>
    <!-- 主体 -->
    <table border="1">
        <tbody>
            <tr v-for="(row, rowIndex) in Map" :key="rowIndex">
                <td v-for="(cell, colIndex) in row" :key="colIndex" :class="`c${cell}`">
                </td>
            </tr>
        </tbody>
    </table>
    <!-- 预览 -->
    <table border="1" class="Preview">
        <tbody>
            <tr v-for="(row, rowIndex) in Previews" :key="rowIndex">
                <td v-for="(cell, colIndex) in row" :key="colIndex" :class="`c${cell}`">
                </td>
            </tr>
        </tbody>
    </table>
    <Dialog :Visible="Visible" :count="count" @close="closeDialog"></Dialog>
</template>

<script setup>
import Dialog from '@/components/dialog.vue';
import { ref, onMounted, onUnmounted } from 'vue'
import { Block, map } from '@/config';
const typeLine = ["S", "Z", "J", "L", "I", "O", 'T']
const Visible = ref(false)
const begin = ref(false)
const Previews = ref([
    [0, 0, 0, 0],
    [0, 0, 0, 0],
    [0, 0, 0, 0],
    [0, 0, 0, 0]
])
const nextType = ref('')
const speed = ref(50)
const nexttype_type = ref(0)
const Map = ref(map)
const rows = map.length;
const nowRow = ref(0)
const count = ref(0)
const RandomColor = ref(0)
const block = ref([]);
const nowcol = ref(4)
const T = ref(null)
const type = ref('')
const type_type = ref(0)
const BeginGame = () => {
    init()
    begin.value = !begin.value
}
onMounted(() => {
    // beginBlock()
    window.addEventListener('keydown', handleKeydown);
});
onUnmounted(() => {
    window.removeEventListener('keydown', handleKeydown);
});
const ReatartGame = () => {
    init()
}
const closeDialog = () => {
    Visible.value = false
}
//判断失败
const ifLost = () => {
    if (countZeros(Map.value[0]) != 12) {
        Visible.value = true
        clearInterval(T.value)
        return false
    }
    return true
}
//初始化
const init = () => {
    setTimeout(() => {

    }, 2000)
    count.value = 0
    speed.value = 50
    nextType.value = typeLine[Math.floor(Math.random() * typeLine.length)]
    nexttype_type.value = Math.floor(Math.random() * Block[nextType.value].length)
    Previews.value = Block[nextType.value][nexttype_type.value]
    Map.value = [
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    ]
    // clearColor()
    changeMapColor()
    beginBlock()
}
//比较数组的函数
const countZeros = (arr) => {
    return arr.filter(item => item === 0).length;
};
//判断是否可以消除
const ifEliminate = () => {
    for (let i = 0; i < 20; i++) {
        if (countZeros(Map.value[i]) == 0) {
            Map.value.splice(i, 1);
            Map.value.unshift([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
            changeMapColor()
            count.value += 5
        }
    }
};
//旋转
const roate = () => {
    const len = Block[type.value].length
    const temp_type = type_type.value
    clearColor()
    if (type_type.value + 1 == len) {
        type_type.value = 0
    } else {
        type_type.value++
    }
    //先看看新的是否符合要求
    const temp = Block[type.value][type_type.value]
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
            if (temp[i][j] != 0 && Map.value[i + nowRow.value][nowcol.value + j] != 0) {
                type_type.value = temp_type
                makeRandomBlock()
                return
            }
        }
    }
    block.value = Block[type.value][type_type.value]
    makeRandomBlock()
}
// 处理键盘事件
const handleKeydown = (event) => {
    switch (event.key) {
        case 'ArrowUp':
            roate()
            break;
        case 'ArrowLeft':
            checkLeft()
            break;
        case 'ArrowRight':
            checkRight()
            break;
        case 'ArrowDown':
            moveDown()
            break;
    }
};
//一键下移
const moveDown = () => {
    clearInterval(T.value)
    while (check()) {
        clearColor()
        nowRow.value++
        makeRandomBlock()
    }
    changeMap()
    ifEliminate()
    if (ifLost())
        setTimeout(beginBlock, 0);
}
//左移
const checkLeft = () => {
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
            if (block.value[i][j] != 0) {
                const newCol = j + nowcol.value;
                if (newCol == 0 || Map.value[i + nowRow.value][newCol - 1] != 0) {
                    return
                }
            }
        }
    }
    clearColor()
    nowcol.value--
    makeRandomBlock()
    return
}
//右移
const checkRight = () => {
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
            if (block.value[i][j] != 0) {
                const newCol = j + nowcol.value;
                if (newCol == 11 || Map.value[i + nowRow.value][newCol + 1] != 0) {
                    return
                }
            }
        }
    }
    clearColor()
    nowcol.value++
    makeRandomBlock()
    return
}
//生成一个新的格子
const beginBlock = () => {
    RandomColor.value = Math.floor(Math.random() * 7) + 1;
    nowRow.value = 0
    nowcol.value = 4
    type.value = nextType.value
    type_type.value = nexttype_type.value
    block.value = Block[type.value][type_type.value]
    nextType.value = typeLine[Math.floor(Math.random() * typeLine.length)]
    nexttype_type.value = Math.floor(Math.random() * Block[nextType.value].length)
    Previews.value = Block[nextType.value][nexttype_type.value]
    makeRandomBlock();
    T.value = setInterval(() => {
        if (check()) {
            clearColor()
            nowRow.value++
            makeRandomBlock()
        } else {
            clearInterval(T.value)
            changeMap()
            ifEliminate()
            if (ifLost())
                setTimeout(beginBlock, 0);
        }
    }, speed.value * 10)
}
//生成颜色的盒子
const makeRandomBlock = () => {
    // console.log(block.value)
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
            // console.log(block.value[i][j])
            if (block.value[i][j] != 0) {
                // 这里修正了单元格索引计算
                const index = (i + nowRow.value) * 12 + j + nowcol.value
                document.querySelectorAll('td')[index].className = `c${block.value[i][j]}`;
            }
        }
    }
};
//清除颜色
const clearColor = () => {
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
            // console.log(block.value[i][j])
            if (block.value[i][j] != 0) {
                // 这里修正了单元格索引计算+
                const index = (i + nowRow.value) * 12 + j + nowcol.value
                document.querySelectorAll('td')[index].className = ``;
            }
        }
    }
}
//渲染地图颜色
const changeMapColor = () => {
    for (let i = 0; i < 20; i++) {
        for (let j = 0; j < 12; j++) {
            // console.log(block.value[i][j])
            if (Map.value[i][j] != 0) {
                // 这里修正了单元格索引计算
                const index = i * 12 + j
                document.querySelectorAll('td')[index].className = `c${Map.value[i][j]}`;
            } else {
                const index = i * 12 + j
                document.querySelectorAll('td')[index].className = ``;
            }
        }
    }
}
//判断是否可以继续下落
const check = () => {
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
            if (block.value[i][j] != 0) {
                const newRow = i + nowRow.value + 1;
                const newCol = j + nowcol.value;
                if (newRow >= rows || Map.value[newRow][newCol] != 0) {
                    return false;
                }
            }
        }
    }
    return true;
}
//将格子固定到地图上
const changeMap = () => {
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
            if (block.value[i][j] != 0) {
                const newRow = i + nowRow.value;
                const newCol = j + nowcol.value
                Map.value[newRow][newCol] = block.value[i][j]
            }
        }
    }
}
//渲染预览窗口
const makeColorPreview = () => {
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
            // console.log(block.value[i][j])
            if (Previews.value[i][j] != 0) {
                // 这里修正了单元格索引计算
                const index = (i + nowRow.value) * 12 + j + nowcol.value
                document.querySelectorAll('td')[index].className = `c${Previews.value[i][j]}`;
            } else {
                const index = (i + nowRow.value) * 12 + j + nowcol.value
                document.querySelectorAll('td')[index].className = ``;
            }
        }
    }
}
</script>

<style scoped>
.slider-demo-block {
    max-width: 600px;
    display: flex;
    align-items: center;
}

.slider-demo-block .el-slider {
    margin-top: 0;
    margin-left: 12px;
}

.Preview {
    position: absolute;
    z-index: 100;
    right: 80px;
    top: 0px;
}

.actionArea {
    position: absolute;
    z-index: 100
}

#video-background {
    z-index: 0;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

td {
    width: 30px;
    height: 30px;
    user-select: none;
    border: 1px solid #ddd;
    /* 边框颜色设置为浅灰色 */
    /* 禁用文本选择 */
    outline: none;
    /* 禁用聚焦时的轮廓 */
}

table {
    position: relative;
    margin: 30px auto;
    z-index: 100;
}

table,
tbody,
tr {
    z-index: 100;
    user-select: none;
    border: none;
    border: 1px solid #ddd;
    /* 边框颜色设置为浅灰色 */
    /* 禁用文本选择 */
    outline: none;
    /* 禁用聚焦时的轮廓 */
}

.c1 {
    background-color: red;
}

.c2 {
    background-color: orange;
}

.c3 {
    background-color: yellow;
}

.c4 {
    background-color: green;
}

.c5 {
    background-color: blue;
}

.c6 {
    background-color: indigo;
}

.c7 {
    background-color: violet;
}
</style>
